﻿using Common.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace CTools.Areas.Strs.Controllers
{
    public class JsonConvertController : CTools.Controllers.BaseController
    {
        // GET: Strs/JsonConvert

        private static Dictionary<string, Type> dic = new Dictionary<string, Type>();
        private static object objLock = new object();
        private static bool loadSuccess = false;
        public JsonConvertController()
        {
            if (loadSuccess == false)
            {
                lock (objLock)
                {
                    if (loadSuccess == false)
                    {
                        foreach (var item in GetClasses(""))
                        {
                            foreach (var itemMethod in GetClassMethods(item))
                            {
                                dic.Add(itemMethod.Key, itemMethod.Value);
                            }
                        }
                        loadSuccess = true;
                    }
                }
            }
        }

        static List<Type> GetClasses(string nameSpace)
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            List<Type> classlist = new List<Type>();

            foreach (Type type in asm.GetTypes())
            {
                if (type.BaseType.Name.ToLower() != "object" && (string.IsNullOrEmpty(nameSpace) || type.Namespace == nameSpace) && type.Name != "MvcApplication")
                    classlist.Add(type);
            }
            return classlist;
        }
        static Dictionary<string, Type> GetClassMethods(Type classType)
        {
            Dictionary<string, Type> methodList = new Dictionary<string, Type>();

            foreach (MethodInfo mInfo in classType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
            {
                if (mInfo.Name.StartsWith("get_") == false && mInfo.Name.StartsWith("set_") == false && methodList.ContainsKey(classType.FullName + "." + mInfo.Name) == false)
                    methodList.Add(classType.FullName + "." + mInfo.Name, mInfo.ReturnType);
            }

            return methodList;
        }
        public ActionResult ToClass()
        {
            return View();
        }
        public ActionResult JsonToClass(string str)
        {
            string resStr = StrToClass(str, "");
            if (string.IsNullOrEmpty(resStr) == false)
            {
                doResult.EnumCode = Common.Msg.EnumCode.Success;
                doResult.Data = resStr;
            }
            return Json(doResult, JsonRequestBehavior.AllowGet);
        }

        public string StrToClass(string str, string className)
        {
            str = str.Trim();
            Dictionary<string, object> dic = null;
            if (str.Replace("\r", "").Replace("\n", "").Replace(" ", "").StartsWith("[{") && str.Replace("\r", "").Replace("\n", "").Replace(" ", "").EndsWith("}]"))
            {
                List<Dictionary<string, object>> listDic = Common.Serialize.JsonHelper.ToObject<List<Dictionary<string, object>>>(str);
                dic = listDic.FirstOrDefault();
            }
            else if (str.Replace("\r", "").Replace("\n", "").Replace(" ", "").StartsWith("{") && str.Replace("\r", "").Replace("\n", "").Replace(" ", "").EndsWith("}"))
            {
                dic = Common.Serialize.JsonHelper.ToObject<Dictionary<string, object>>(str);
            }
            else
            {
                return "";
            }
            StringBuilder classStr = new StringBuilder("    public class " + className);
            if (string.IsNullOrEmpty(className))
            {
                if (dic.Count == 1)
                    return StrToClass(dic.First().Value.ToString(), dic.First().Key);
                else
                    classStr.Append("ClassName");
            }
            classStr.Append("\r\n    {");

            string dataType = "";
            DateTime dtime = DateTime.Now;
            foreach (var item in dic)
            {
                if (item.Value == null)
                {
                    dataType = "string";
                }
                else if (item.Value.ToString().ToLower().Equals("true") || item.Value.ToString().ToLower().Equals("false"))
                {
                    dataType = "bool";
                }
                else if (RegexLib.IsNumber(item.Value.ToString()))
                {
                    if (RegexLib.IsInt(item.Value.ToString()))
                        dataType = "int";
                    else
                        dataType = "long";
                }
                else if (item.Value.ToString().Contains('.') && RegexLib.IsValidDecimal(item.Value.ToString()))
                {
                    dataType = "decimal";
                }
                else if (DateTime.TryParse(item.Value.ToString(), out dtime))
                {
                    dataType = "DateTime";
                }
                else if (item.Value.ToString().Replace("\r", "").Replace("\n", "").Replace(" ", "").StartsWith("{") && item.Value.ToString().Replace("\r", "").Replace("\n", "").Replace(" ", "").EndsWith("}"))
                {
                    dataType = item.Key + "Item";
                    string childClassStr = StrToClass(item.Value.ToString(), dataType);
                    if (string.IsNullOrEmpty(childClassStr) == false)
                    {
                        childClassStr += classStr.ToString();
                        classStr.Clear().Append(childClassStr);
                    }
                }
                else if (item.Value.ToString().Replace("\r", "").Replace("\n", "").Replace(" ", "").StartsWith("[{") && item.Value.ToString().Replace("\r", "").Replace("\n", "").Replace(" ", "").EndsWith("}]"))
                {
                    if (item.Key.ToLower().StartsWith("list") && item.Key.Length > 4)
                    {
                        dataType = item.Key.Substring(3, item.Key.Length - 4);
                    }
                    else if (item.Key.ToLower().EndsWith("list") && item.Key.Length > 4)
                    {
                        dataType = item.Key.Substring(0, item.Key.Length - 4);
                    }
                    else if (item.Key.ToLower().EndsWith("s") && item.Key.Length > 1)
                    {
                        dataType = item.Key.Substring(0, item.Key.Length - 1);
                    }
                    else
                        dataType = item.Key + "Item";
                    string childClassStr = StrToClass(item.Value.ToString(), dataType);
                    if (string.IsNullOrEmpty(childClassStr) == false)
                    {
                        childClassStr += classStr.ToString();
                        classStr.Clear().Append(childClassStr);
                    }
                    dataType = "List&#60;" + dataType + "&#62;";
                }
                else
                {
                    dataType = "string";
                }
                classStr.Append("\r\n        /// &#60;summary&#62;\r\n        /// \r\n        /// &#60;/summary&#62;\r\n        [Description(\"\")]\r\n        public " + dataType + " " + item.Key + " { get; set; }");
            }
            classStr.Append("\r\n    }\r\n");
            return classStr.ToString();
        }
    }
}